package com.yami.shop.search.platform.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.yami.shop.bean.enums.ProdType;
import com.yami.shop.bean.event.EsProductActivityInfoEvent;
import com.yami.shop.bean.param.EsProductParam;
import com.yami.shop.bean.vo.search.ProductSearchVO;
import com.yami.shop.common.constants.CacheNames;
import com.yami.shop.common.constants.EsCacheNames;
import com.yami.shop.common.enums.EsRenovationProductSortEnum;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.common.util.EsPageVO;
import com.yami.shop.common.util.RedisUtil;
import com.yami.shop.search.common.constant.EsConstant;
import com.yami.shop.search.common.manager.ProductSearchManager;
import com.yami.shop.search.common.param.EsPageParam;
import com.yami.shop.search.common.service.SearchProductService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.List;
import java.util.Objects;

/**
 * @author lgh
 */
@RestController
@RequestMapping("/platform/search/prod")
@Tag(name = "平台端商品搜索接口")
public class EsProdctController {

    @Autowired
    private SearchProductService searchProductService;

    @Autowired
    private ProductSearchManager productSearchManager;

    @Autowired
    private ApplicationEventPublisher eventPublisher;

    @GetMapping("/page")
    @Operation(summary =  "商品信息列表", description = "商品信息列表")
    public ServerResponseEntity<EsPageVO<ProductSearchVO>> page(@Valid EsPageParam pageParam, @ParameterObject EsProductParam productParam) {
        productParam.setFetchSource(EsConstant.PLATFORM_FETCH_SOURCE);
        EsPageVO<ProductSearchVO> searchPage =  searchProductService.adminPage(pageParam, productParam);
        return ServerResponseEntity.success(searchPage);
    }

    @GetMapping("/scorePage")
    @Operation(summary =  "积分商品信息列表", description = "积分商品信息列表")
    public ServerResponseEntity<EsPageVO<ProductSearchVO>> scorePage(@Valid EsPageParam pageParam, @ParameterObject EsProductParam productParam) {
        productParam.setFetchSource(EsConstant.SHOP_FETCH_SOURCE);
        EsPageVO<ProductSearchVO> searchPage =  searchProductService.adminPage(pageParam, productParam);
        return ServerResponseEntity.success(searchPage);
    }

    @GetMapping("/renovationPage")
    @Operation(summary =  "商品信息列表(装修商品列表)", description = "商品信息列表(装修商品列表)")
    public ServerResponseEntity<EsPageVO<ProductSearchVO>> renovationPage(@Valid EsPageParam pageParam, @ParameterObject EsProductParam productParam) {
        Long size = null;
        if(Objects.equals(productParam.getShowSpuType(),1)){
            if(Objects.equals(productParam.getEsRenovationSpuSort(), EsRenovationProductSortEnum.CREATE_TIME_ASC.value()) || Objects.equals(productParam.getEsRenovationSpuSort(),EsRenovationProductSortEnum.CREATE_TIME_DESC.value())){
                productParam.setSort(productParam.getEsRenovationSpuSort());
            }else {
                // 获取指定规则的商品ids并返回大小
                size = getSpuIds(pageParam, productParam);
            }
        }
        EsPageVO<ProductSearchVO> searchPage = searchProductService.renovationPage(pageParam, productParam,size);
        if (CollUtil.isEmpty(searchPage.getRecords())) {
            return ServerResponseEntity.success(searchPage);
        }
        if (CollUtil.isNotEmpty(searchPage.getRecords())) {
            // 如果包含秒杀、团购活动商品，就插入活动信息
            long count = searchPage.getRecords().stream().filter(product -> Objects.equals(product.getProdType(), ProdType.PROD_TYPE_GROUP.value()) || Objects.equals(product.getProdType(), ProdType.PROD_TYPE_SECKILL.value())).count();
            if (count > 0) {
                eventPublisher.publishEvent(new EsProductActivityInfoEvent(productParam.getProdType(), searchPage.getRecords()));
            }
        }
        return ServerResponseEntity.success(searchPage);
    }

    @GetMapping("/prodExport")
    @Operation(summary =  "商品导出", description = "商品导出")
    @PreAuthorize("@pms.hasPermission('prod:prod:exportProd')")
    public void prodExport(HttpServletResponse response, @ParameterObject EsProductParam productParam) {
        productParam.setShopId(null);
        searchProductService.export(response, productParam);
    }

    private Long getSpuIds(EsPageParam pageParam, EsProductParam productParam) {
        Long shopId = Objects.isNull(productParam.getShopId()) ? 0L :  productParam.getShopId();
        String key = EsCacheNames.RENOVATION_PRODUCT_IDS_CACHE + CacheNames.UNION + shopId +
                CacheNames.UNION_KEY + productParam.getEsTimeRange() + CacheNames.UNION_KEY + productParam.getEsRenovationSpuSort();
        if(!RedisUtil.hasKey(key)){
            productSearchManager.addRenovationSpuCache(key,productParam,shopId, EsCacheNames.RENOVATION_PRODUCT_IDS_CACHE_TIME);
        }
        Long size = RedisUtil.getListSize(key);
        long startNum = (long) (pageParam.getCurrent() - 1) * pageParam.getSize();
        long endNum = (long) pageParam.getCurrent() * pageParam.getSize() - 1;
        endNum = Math.min(endNum,size);
        List prodIds = RedisUtil.getListRange(key, startNum, endNum);
        productParam.setProdIds(prodIds);
        return size;
    }
}
